home *** CD-ROM | disk | FTP | other *** search
- /* output.c --- saving and transferring data. */
-
- #include "d2rd.h"
- #include <stdio.h>
- #include <stdarg.h>
- #include <string.h>
- #include <stdlib.h>
- #include "kernel.h"
- #include "output.h"
- #include "visdelay.h"
- #include "font.h"
- #include "flex.h"
-
- #define VERT_SIZE (int)(A4_HEIGHT*180*256) /* height of page in Draw internal units */
-
- /* Forward declarations. */
-
- void output_sprite (outputter, FILE *);
- void output_draw (outputter, FILE *);
- size_t ram_write (const void *, size_t, size_t, FILE *);
-
- static char *my_buf;
- static char *your_buf;
- static int buf_size;
- static int buf_pos;
- static wimp_t dest_task;
- static int your_ref;
-
-
- void
- send_buf (int size)
- {
- wimp_msgstr msg;
- wimp_eventstr b;
-
- msg.hdr.action = wimp_MRAMTRANSMIT;
- msg.hdr.your_ref = your_ref;
- msg.hdr.size = sizeof (wimp_msgstr);
- msg.data.ramtransmit.addr = your_buf;
- msg.data.ramtransmit.nbyteswritten = size;
- wimpt_noerr (wimp_transferblock (wimpt_task (), my_buf, dest_task, your_buf, size));
- if (size != buf_size)
- wimpt_noerr (wimp_sendmessage (wimp_ESEND, &msg, dest_task));
- else
- {
- wimpt_noerr (wimp_sendmessage (wimp_ESENDWANTACK, &msg, dest_task));
- for (;;)
- {
- wimpt_noerr (wimp_poll (0x1973, &b));
- switch (b.e)
- {
- case wimp_ESEND:
- case wimp_ESENDWANTACK:
- if (b.data.msg.hdr.your_ref == msg.hdr.my_ref)
- {
- dest_task = b.data.msg.hdr.task; /* paranoid */
- your_ref = b.data.msg.hdr.my_ref;
- your_buf = b.data.msg.data.ramfetch.addr;
- buf_size = b.data.msg.data.ramfetch.nbytes;
- my_buf = realloc (my_buf, buf_size);
- return;
- }
- else
- tfatal ("EXPORT FAILED!");
- #if 0
- tfatal ("References fail (%d, %d, %d, %d)", msg.hdr.my_ref, msg.hdr.your_ref, b.data.msg.hdr.my_ref, b.data.msg.hdr.your_ref);
- #endif
- case wimp_EACK:
- fatal ("RAM transfer failed");
- break;
-
- default:
- #if 0
- fatal ("unwanted event: %d", b.e);
- #endif
- continue;
- }
- break;
- }
- }
- } /* send_buf */
-
-
-
- void
- output_send (wimp_msgstr *m)
- {
- FILE *f = NULL;
-
- your_buf = m->data.ramfetch.addr;
- buf_size = m->data.ramfetch.nbytes;
- dest_task = m->hdr.task;
- your_ref = m->hdr.my_ref;
-
- /* If the buffer on the other size is large enough, we can get rid of the
- sprite at once. */
-
- if (saveas_filetype == 0xff9 && buf_size > flex_size ((flex_ptr) &which_menu->area))
- {
- buf_pos = 0;
- buf_size = 0;
- my_buf = (char *) &which_menu->area->number;
- send_buf (flex_size ((flex_ptr) &which_menu->area) - 4);
- return;
- }
-
- my_buf = xmalloc (buf_size);
- buf_pos = 0;
-
- visdelay_begin ();
-
- switch (saveas_filetype)
- {
- case 0xff9:
- ram_write (&which_menu->area->number, 1, which_menu->area->size - 4, f);
- break;
- case 0xaff:
- output_draw (&ram_write, f);
- break;
- default:
- tfatal ("But I have never heard of filetype 0x%x!", saveas_filetype);
- break;
- }
-
- wimp_create_menu ((wimp_menustr *) -1, 0, 0);
- send_buf (buf_pos);
- visdelay_end ();
- free (my_buf);
- } /* saveas_send */
-
-
-
- size_t
- ram_write (const void *b, size_t size, size_t nmemb, FILE *f)
- {
- int n = size * nmemb, ret = n;
- char *from = (char *)b;
-
- f = f;
-
- for (;;)
- {
- if (buf_pos + n < buf_size)
- {
- for (; n; buf_pos++, from++, n--)
- my_buf[buf_pos] = *from;
- break;
- }
- for (; buf_pos < buf_size; buf_pos++, from++, n--)
- my_buf[buf_pos] = *from;
- send_buf (buf_size);
- buf_pos = 0;
- }
- return (ret);
- } /* ram_write */
-
-
- void
- output_saveas (char *name)
- {
- char cmd[300];
- FILE *f;
-
- wimp_create_menu ((wimp_menustr *)-1, 0, 0);
- visdelay_begin ();
-
- f = fopen (name, "wb");
- if (f == NULL)
- {
- fatal ("Can't open file `%s'.", name);
- return;
- }
-
- switch (saveas_filetype)
- {
- case 0xff9:
- fwrite (&which_menu->area->number, 1, which_menu->area->size - 4, f);
- sprintf (cmd, "settype %s ff9", name);
- break;
-
- case 0xaff:
- output_draw (&fwrite, f);
- sprintf (cmd, "settype %s aff", name);
- break;
-
- default:
- tfatal ("But I have never heard of filetype 0x%x!", saveas_filetype);
- break;
- }
- fclose (f);
- _kernel_oscli (cmd);
- visdelay_end ();
- } /* output_saveas */
-
- /* The routines below are concerned with outputting a draw format file. */
-
- static int
- write_n (FILE *f, outputter put_out, int n, ...)
- {
- va_list ap;
- int *a, i;
-
- va_start (ap, n);
- a = (int *) xmalloc (n * sizeof (int));
- for (i = 0; i < n; i++)
- a[i] = va_arg (ap, int);
- va_end (ap);
- i = put_out (a, sizeof (int), n, f);
- free (a);
- return (i);
- } /* write_n */
-
-
-
- void
- output_draw (outputter put_out, FILE *f)
- {
- struct display *w = which_menu;
- struct page *p = w->page;
- struct dvi_file *df = w->file;
- struct text *txt;
- struct rule *rl;
- int *dvi_to_font = xcalloc (sizeof (int), 256);
- int *font_to_dvi = xcalloc (sizeof (int), 256);
- int max_font = 1, size = 0, rsize, i, j, k, l, t, x, y;
- char *s;
-
- /*
- ** hor_offset holds the horizontal offset for all objects, in
- ** millipoints. Usually 1in, or 72000 millipoints.
- */
- int hor_offset = w->hor_offset;
-
- /*
- ** ver_offset holds the distance from the bottom of the page to
- ** the offset point, normally 1in from the top edge. This is
- ** held in millipoints.
- */
- int ver_offset = w->ver_size - w->ver_offset;
-
- /* Output DrawFile header. */
-
- put_out ("Draw", 1, 4, f);
- write_n (f, put_out, 2, 201, 0);
- put_out ("Preview ", 1, 12, f);
-
- #define VS (11.69*180.0*256.0*(10000.0 / 14142.0))
- write_n (f, put_out, 4, 0, 0, VS, VERT_SIZE); /* avoid constant-overflow! */
-
- /* Build and output the font information object. */
-
- txt = p->texts;
- for (t = 0; t < p->text_max; t++, txt++)
- if (dvi_to_font[txt->font] == 0)
- {
- font_to_dvi[max_font] = txt->font;
- dvi_to_font[txt->font] = max_font;
- size += 2 + strlen (df->fonts[txt->font]->name);
- max_font++;
- }
- if (size)
- {
- rsize = (size + 3) & ~3;
- write_n (f, put_out, 2, 0, rsize + 8);
- for (i = 1; i < max_font; i++)
- {
- s = df->fonts[font_to_dvi[i]]->name;
- put_out (&i, 1, 1, f);
- put_out (s, 1, 1 + strlen (s), f);
- }
- l = 0;
- for (i = size; i < rsize; i++)
- put_out (&l, 1, 1, f);
- }
-
-
- /* Output the text blobs. */
-
- for (t = 0, txt = p->texts; t < p->text_max; t++, txt++)
- {
- l = strlen (&p->chars[txt->text]);
- i = (l + 4) & ~3;
- size = 40 * df->fonts[txt->font]->size;
- font_converttoos (hor_offset + txt->x, ver_offset - txt->y, &x, &y);
- font_converttoos (hor_offset + txt->rx, ver_offset - txt->ty, &j, &k);
-
- x *= 256, y *= 256, j *= 256, k *= 256;
-
- write_n (f, put_out, 4, 1, 52 + i, x, y);
- write_n (f, put_out, 2, j, k);
- write_n (f, put_out, 7, 0, 0xffffff00, dvi_to_font[txt->font], size, size, x, y);
- put_out (&p->chars[txt->text], 1, l, f);
- k = 0;
- for (j = l; j < i; j++)
- put_out (&k, 1, 1, f);
- }
-
- /* Output rules. */
-
- for (t = 0, rl = p->rules; t < p->rule_max; t++, rl++)
- {
- font_converttoos ((hor_offset + rl->x) * 256,
- (ver_offset - rl->y) * 256, &x, &y);
- font_converttoos (rl->w * 256, rl->h * 256, &j, &k);
-
- write_n (f, put_out, 6, 2, 24 + 11 * 4, x, y, x + j, y + k);
- write_n (f, put_out, 11, -1, 0, k, 0x20100042, 2, x, y+k/2, 8, x + j, y+k/2, 0);
- }
- } /* output_draw */
-
- /* EOF */
-